package laravel.mvc.model;

import entity_model.Attribute;
import entity_model.Entity;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import laravel.EntityClass;
import laravel.Laravel;
import laravel.mvc.MvcComponent;
import utils.VirtualFolder;
import utils.titles.Title;
import php.code.functions.Functions;
import php.code.routines.Constructor;

import static php.code.Visibility.PROTECTED;
import static php.code.functions.TextLayout.INLINE;

public abstract class AbstractModel extends MvcComponent{

    private static final VirtualFolder FOLDER = Laravel.APP_FOLDER.create("models");

    private final ObservableList<String> fillable = FXCollections.observableArrayList();

    public final EntityClass entityClass;
    private BaseSubModel baseModel;

    AbstractModel(Laravel laravel, Title title, Entity entity) {
        super(title, entity);

        entityClass = new EntityClass(FOLDER, title, getBaseSubModelName(laravel, entity), entity);
        laravel.files.add(entityClass.getFile());

        createProperties();
    }

    private String getBaseSubModelName(Laravel laravel, Entity entity) {
        Entity base = entity.getBaseEntity();

        if (base == null)
            return "Eloquent";

        fillable.add("id");

        if (!laravel.baseSubModels.containsKey(base))
            new BaseSubModel(laravel, base);

        baseModel = laravel.baseSubModels.get(base);

        return baseModel.getTitle().toUpperCamel();
    }

    private void createProperties() {
        for(Attribute attribute : entity.getAttributes()){
            Title title = attribute.getTitle();

//            if (!attribute.isFillable() && !title.toLowerCamel().equals("id")) FIXME
//                  title = title.suffix("Id");

            fillable.add(title.toSnakeCase());
        }

        if (fillable.size() > 0)
            entityClass.createProperty(PROTECTED, "fillable", Functions.array(INLINE, fillable));

/*        List<String> hidden = entityClass.entity FIXME
                .getAttributes()
                .stream()
                .filter(Attribute::isHidden)
                .map(attribute -> LOWER_CAMEL.to(SNAKE_CASE, attribute.toString()))
                .collect(Collectors.toList());

        if (hidden.size() > 0)
            entityClass.createProperty(PROTECTED, "hidden", array(INLINE, hidden));*/
    }

    public EntityClass getEntityClass() {
        return entityClass;
    }

    public BaseSubModel getBaseModel() {
        return baseModel;
    }

    public ObservableList<String> getFillable() {
        return fillable;
    }

    public Constructor getConstructor() {
        return entityClass.getDefaultConstructor();
    }
}
